using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Oops.Xna.Framework.Physics;
using Oops.Xna.Framework.Input;

namespace Oops.Xna.Framework.Testing.App
{
	public class Example9Screen : ExampleScreen, IHeightmapCollisionMeshCallback 
	{
		// Content.
		private Texture2D texture;
		private Heightmap heightmap;
		private Vector3 heightmapScale = Vector3.One * 30.0f;
		private Vector3 heightmapPosition = Vector3.Down * 20.0f;
		private Matrix heightmapOrientation = Matrix.CreateRotationY(MathHelper.ToRadians(-10.0f));

		private CollisionMesh mesh;
		
		public Example9Screen(Game game) : base(game, "Example9") {	}

		#region ExampleScreen Members

		protected override void DrawWorld(Effect effect, EffectParameter world, EffectParameter texture)
		{
			// Draw the ground.
			world.SetValue(Matrix.CreateScale(this.heightmapScale) * this.heightmapOrientation * Matrix.CreateTranslation(this.heightmapPosition));
			texture.SetValue(this.texture);
			effect.CommitChanges();

			//this.GraphicsDevice.RenderState.FillMode = FillMode.WireFrame;
			this.GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionNormalTexture>(PrimitiveType.TriangleList, this.heightmap.Vertices, 0, this.heightmap.Vertices.Length, this.heightmap.Indices, 0, this.heightmap.Indices.Length / 3);
		}

		protected override void Reset()
		{
			// Start with 25 boxes and 50 spheres.
			this.Reset(25, 50);

			// Create the heightmap.
			this.heightmap = new Heightmap(8, 8);

			// Create the ground plane.  
			this.mesh = new CollisionMesh(new HeightmapCollsionMeshProxy(this, this.heightmapScale));
						
			// Create a collision group and add the mesh.
			CollisionGroup collisionGroup = new CollisionGroup();
			collisionGroup.CollisionShapes.Add(this.mesh);
#if QUATERNION_ORIENTATION
            Quaternion orientation = Quaternion.CreateFromRotationMatrix(this.heightmapOrientation);
#else
			Matrix orientation = this.heightmapOrientation;
#endif
			collisionGroup.UpdateTransform(ref this.heightmapPosition, ref orientation);

			// Add the mesh's collision group to the collision system.
			this.physics.CollisionSystem.CollisionGroups.Add(collisionGroup);
		}

		#endregion

		#region DrawableGameComponent Members

		protected override void LoadContent()
		{
			// Load all the used graphic resources.
			this.texture = this.Game.GetContent().Load<Texture2D>(@".\Content\Textures\plane");
						
			// Call inherited method.
			base.LoadContent();
		}

		#endregion

		#region IHeightmapCollisionMeshCallback Members

		public Point Size
		{
			get { return new Point(this.heightmap.Width, this.heightmap.Depth); }
		}

		public float GetSample(int x, int y)
		{
			return this.heightmap.Vertices[x + y * this.heightmap.Width].Position.Y; 
		}

		#endregion
	}
}
